package com.hex.ds.hdrs.common.helper;

import com.hex.bigdata.hbda.base.Page;
import com.hex.ds.hdrs.agent.service.AgentManager;
import com.hex.ds.hdrs.agent.service.AgentSession;
import com.hex.ds.hdrs.agent.vo.AgentSessionVO;
import com.hex.ds.hdrs.app.vo.AppAgentVo;
import com.hex.ds.hdrs.app.vo.AppSessionVO;
import com.hex.ds.hdrs.common.constant.Const;
import com.hex.ds.hdrs.common.exception.BizException;
import com.hex.ds.hdrs.common.utils.ListUtil;
import com.hex.ds.hdrs.engine.manager.RunningManager;
import com.hex.ds.hdrs.engine.manager.ToDoManager;
import com.hex.ds.hdrs.engine.manager.ToRunManager;
import com.hex.ds.hdrs.period.job.po.JobTask;
import com.hex.ds.hdrs.period.job.po.PeriodJob;
import com.hex.ds.hdrs.period.task.po.PeriodTask;
import lombok.extern.slf4j.Slf4j;

import java.util.*;

/**
 * @author lwz
 * @date 2020-12-29
 * @des
 */
@Slf4j
public class RamHelper {
    private static final byte[] runningSyn = {};
    private static final byte[] toRunSyn = {};
    private static final byte[] toDoSyn = {};
    private static final byte[] jobTaskSyn = {};
    private static final byte[] taskSyn = {};
    private static ToDoManager toDoManager = ToDoManager.getInstance();
    private static ToRunManager toRunManager = ToRunManager.getInstance();
    private static RunningManager runningManager = RunningManager.getInstance();
    private static AgentManager agentManager = AgentManager.getInstance();

    public static Integer getCycleJobTodo(String appCode, String bizDate) {
        Integer count = 0;
        List<JobTask> toDoList = toDoManager.getToDoJobList();
        if (!ListUtil.isEmpty(toDoList)) {
            for (int i = 0; i < toDoList.size(); i++) {
                JobTask jobTask = toDoList.get(i);
                if (jobTask != null && appCode.equals(jobTask.getAppCode()) && bizDate.equals(jobTask.getBizDate())) {
                    count++;
                }
            }
        }
        return count;
    }

    public static Integer getCycleJobToRun(String appCode, String bizDate) {
        Integer count = 0;
        List<JobTask> toRunList = toRunManager.getToRunJobList();
        if (!ListUtil.isEmpty(toRunList)) {
            for (int i = 0; i < toRunList.size(); i++) {
                JobTask jobTask = toRunList.get(i);
                if (jobTask != null && appCode.equals(jobTask.getAppCode()) && bizDate.equals(jobTask.getBizDate())) {
                    count++;
                }
            }
        }
        return count;
    }

    public static Integer getCycleJobRunning(String appCode, String bizDate) {
        Integer count = 0;
        List<PeriodTask> runningList = runningManager.getRunTaskList();
        if (!ListUtil.isEmpty(runningList)) {
            for (int i = 0; i < runningList.size(); i++) {
                PeriodTask task = runningList.get(i);
                if (task != null && appCode.equals(task.getAppCode()) && bizDate.equals(task.getBizDate())) {
                    count++;
                }
            }
        }
        return count;
    }

    public static Integer getCycleJobFinish(List<Map> list) {
        Integer count = 0;
        for (Map map1 : list) {
            if (map1.containsKey("jobStatus")){
                if (Const.JOB_DO_SUCCESS.equals(map1.get("jobStatus"))) {
                    count = Integer.valueOf(String.valueOf(map1.get("count")));
                }
            }else if(map1.containsKey("JOBSTATUS")){
                if (Const.JOB_DO_SUCCESS.equals(map1.get("JOBSTATUS"))) {
                    count = Integer.valueOf(String.valueOf(map1.get("COUNT")));
                }
            }
        }
        return count;
    }

    public static Integer getCycleJobNoFinish(List<Map> list) {
        Integer count = 0;
        for (Map map1 : list) {
            if (map1.containsKey("jobStatus")){
                if (!Const.JOB_DO_SUCCESS.equals(map1.get("jobStatus"))) {
                    count = Integer.valueOf(String.valueOf(map1.get("count")));
                }
            }else if(map1.containsKey("JOBSTATUS")){
                if (!Const.JOB_DO_SUCCESS.equals(map1.get("JOBSTATUS"))) {
                    count = Integer.valueOf(String.valueOf(map1.get("COUNT")));
                }
            }

        }
        return count;
    }

    public static AppAgentVo getAgentUsageRate(AppAgentVo appAgentVo) {
        try {
            String agentStatus = (Const.AGENT_STATUS_STOP.equals(appAgentVo.getAgentStatus())) ? Const.AGENT_HA_STATUS_STOP : appAgentVo.getAgentHaStatus();
            appAgentVo.setAgentHaStatus(agentStatus);
            AgentSession agentSession = agentManager.getAgentSession(appAgentVo.getAgentCode());
            Integer resNumUsage = agentSession.getCurResNum().get();
            Integer conNumUssge = agentSession.getCurConcurrentNum().get();
            appAgentVo.setUsedResNum(resNumUsage);
            appAgentVo.setUsedConNum(conNumUssge);

            appAgentVo.setResUsageRate(resNumUsage * 100 / appAgentVo.getResNum());
            appAgentVo.setConUsageRate(conNumUssge * 100 / appAgentVo.getConcurrentNum());
        } catch (BizException e) {
            log.error("【getAgentUsageRate】异常:{}" , e.getErrMsg(), e);
        }
        return appAgentVo;
    }

    /**
     * 获取当前应用，不同业务日期作业数量
     *
     * @param appCode
     * @return
     */
    public static Map getCycleJobRunInfCurrentApp(String appCode) {
        try {
            List<JobTask> todoRunList = toDoManager.getToDoJobList();
            List<JobTask> toRunJobList = toRunManager.getToRunJobList();
            List<JobTask> runningList = runningManager.getRunJobList();
            Map resultMap = new HashMap();
            Map resMap = new HashMap();
            getJobToDo(todoRunList, appCode, resultMap);
            getCycleJobToRun(toRunJobList, appCode, resultMap);
            getCycleJobRunning(runningList, appCode, resultMap);
            Object[] key = resultMap.keySet().toArray();
            Arrays.sort(key);
            for (int i = 0; i < key.length; i++) {
                resMap.put(key[i], resultMap.get(key[i]));
            }
            return resMap;
        } catch (Exception e) {
            log.error("获取不同业务日期作业数量出错:{}" , e.getMessage(), e);
            throw e;
        }
    }

    /**
     * 获取当前应用，不同业务日期正在执行作业数量
     *
     * @param resultMap
     * @param runningList
     * @param appCode
     */
    public static void getCycleJobRunning(List<JobTask> runningList, String appCode, Map resultMap) {
        if (!ListUtil.isEmpty(runningList)) {
            synchronized (runningSyn) {
                for (int i = 0; i < runningList.size(); i++) {
                    JobTask jobTask = runningList.get(i);
                    if (jobTask != null && appCode.equals(jobTask.getAppCode())) {
                        if (resultMap.containsKey(jobTask.getBizDate())) {
                            Map dataMap = (Map) resultMap.get(jobTask.getBizDate());
                            Integer count = (Integer) dataMap.get("runningCount");
                            dataMap.put("runningCount", count + 1);
                        } else {
                            Map dataMap = new HashMap();
                            dataMap.put("bizDate", jobTask.getBizDate());
                            dataMap.put("todoRunCount", 0);
                            dataMap.put("toRunCount", 0);
                            dataMap.put("runningCount", 1);
                            resultMap.put(jobTask.getBizDate(), dataMap);
                        }
                    }
                }
            }
        }
    }

    public static void getCycleJobToRun(List<JobTask> toRunList, String appCode, Map resultMap) {
        if (!ListUtil.isEmpty(toRunList)) {
            synchronized (toRunSyn) {
                for (int i = 0; i < toRunList.size(); i++) {
                    JobTask jobTask = toRunList.get(i);
                    if (jobTask != null && appCode.equals(jobTask.getAppCode())) {
                        if (resultMap.containsKey(jobTask.getBizDate())) {
                            Map dataMap = (Map) resultMap.get(jobTask.getBizDate());
                            Integer count = (Integer) dataMap.get("toRunCount");
                            dataMap.put("toRunCount", count + 1);
                        } else {
                            Map dataMap = new HashMap();
                            dataMap.put("bizDate", jobTask.getBizDate());
                            dataMap.put("todoRunCount", 0);
                            dataMap.put("toRunCount", 1);
                            dataMap.put("runningCount", 0);
                            resultMap.put(jobTask.getBizDate(), dataMap);
                        }
                    }
                }
            }
            /*for (JobTask jobTask : toRunList) {
                if (appCode.equals(jobTask.getAppCode())) {
                    if (resultMap.containsKey(jobTask.getBizDate())) {
                        Map dataMap = (Map) resultMap.get(jobTask.getBizDate());
                        Integer count = (Integer) dataMap.get("toRunCount");
                        dataMap.put("toRunCount", count + 1);
                    } else {
                        Map dataMap = new HashMap();
                        dataMap.put("bizDate", jobTask.getBizDate());
                        dataMap.put("todoRunCount", 0);
                        dataMap.put("toRunCount", 1);
                        dataMap.put("runningCount", 0);
                        resultMap.put(jobTask.getBizDate(), dataMap);
                    }
                }
            }*/
        }
    }

    /**
     * 获取当前应用，不同业务日期待执行作业数量
     *
     * @param toDoList
     * @param appCode
     * @return
     */
    public static void getJobToDo(List<JobTask> toDoList, String appCode, Map resultMap) {
        if (!ListUtil.isEmpty(toDoList)) {
            synchronized (toDoSyn) {
                for (int i = 0; i < toDoList.size(); i++) {
                    JobTask jobTask = toDoList.get(i);
                    if (jobTask != null && appCode.equals(jobTask.getAppCode())) {
                        if (resultMap.containsKey(jobTask.getBizDate())) {
                            Map dataMap = (Map) resultMap.get(jobTask.getBizDate());
                            Integer count = (Integer) dataMap.get("todoRunCount");
                            dataMap.put("todoRunCount", count + 1);
                        } else {
                            Map dataMap = new HashMap();
                            dataMap.put("bizDate", jobTask.getBizDate());
                            dataMap.put("todoRunCount", 1);
                            dataMap.put("toRunCount", 0);
                            dataMap.put("runningCount", 0);
                            resultMap.put(jobTask.getBizDate(), dataMap);
                        }
                    }
                }
            }
            /*for (JobTask jobTask : toDoList) {
                if (appCode.equals(jobTask.getAppCode())) {
                    if (resultMap.containsKey(jobTask.getBizDate())) {
                        Map dataMap = (Map) resultMap.get(jobTask.getBizDate());
                        Integer count = (Integer) dataMap.get("todoRunCount");
                        dataMap.put("todoRunCount", count + 1);
                    } else {
                        Map dataMap = new HashMap();
                        dataMap.put("bizDate", jobTask.getBizDate());
                        dataMap.put("todoRunCount", 1);
                        dataMap.put("toRunCount", 0);
                        dataMap.put("runningCount", 0);
                        resultMap.put(jobTask.getBizDate(), dataMap);
                    }
                }
            }*/
        }
    }

    /**
     * @param dataList
     * @param statusKey
     * @param statusValue
     * @param valuekey
     * @param defaultVaule
     * @return
     */
    public static String getMapStatusValue(List<Map> dataList, String statusKey, String statusValue, String valuekey, String defaultVaule) {
        for (Map dataMap : dataList) {
            if (dataMap.containsKey(statusKey) && statusValue.equals(dataMap.get(statusKey))) {
                return dataMap.get(valuekey).toString();
            }
            if (dataMap.containsKey(statusKey.toUpperCase()) && statusValue.equals(dataMap.get(statusKey.toUpperCase()))) {
                return dataMap.get(valuekey.toUpperCase()).toString();
            }
        }
        return defaultVaule;
    }

    public static String getCycleJobStatusCount(List<Map> dataList, String statusValue) {
        return getMapStatusValue(dataList, "jobStatus", statusValue, "count", "0");
    }

    public static String getCycleStatusCount(List<Map> dataList, String statusValue) {
        return getMapStatusValue(dataList, "task_status", statusValue, "count", "0");
    }

    public static String getCronStatusCount(List<Map> dataList, String statusValue) {
        return getMapStatusValue(dataList, "exec_status", statusValue, "count", "0");
    }

    public static void delJobInListNotInMap(List<JobTask> jobTaskList, Map<String, JobTask> jobTaskMap) {
        try {
            List<JobTask> delList = new ArrayList<>();
            synchronized (jobTaskSyn) {
                for (int i = 0; i < jobTaskList.size(); i++) {
                    JobTask jobTask = jobTaskList.get(i);
                    if (jobTaskMap.get(jobTask.getJobCode()) == null) {
                        delList.add(jobTask);
                    }
                }
                jobTaskList.removeAll(delList);
            }
        } catch (Exception e) {
            log.error("【delJobInListNotInMap】异常:{}" ,e.getMessage(), e);
        }
    }

    public static List<PeriodTask> delTaskInListNotInMap(List<PeriodTask> taskList, Map<String, PeriodTask> taskMap) {
        List<PeriodTask> delList = new ArrayList<>();
        try {
            synchronized (taskSyn) {
                for (int i = 0; i < taskList.size(); i++) {
                    PeriodTask task = taskList.get(i);
                    if (taskMap.get(task.getTaskCode()) == null) {
                        delList.add(task);
                    }
                }
                taskList.removeAll(delList);
            }
        } catch (Exception e) {
            log.error("【delTaskInListNotInMap】异常:{}" , e.getMessage(), e);
        }
        return delList;
    }

    /**
     * @Method: formatJobListPage
     * @Param: [taskList, page]
     * @Return: java.util.List<com.hex.ds.hdrs.period.job.po.PeriodJob>
     * @Description： 作业 分页处理
     * @Author： jd.chen
     * @Date： 2021/7/12 19:52
     * @Version： V1.0
     */
    public static List<PeriodJob> formatJobListPage(List<PeriodJob> taskList, Page page) {
        if (ListUtil.isEmpty(taskList)) {
            page.setTotal(0);
            return taskList;
        }
        page.setTotal(taskList.size());
        Integer startIndex = page.getPageIndex() * page.getPageSize();
        Integer endIndex = (page.getPageIndex() + 1) * page.getPageSize();
        if (startIndex == taskList.size()) {
            startIndex = (page.getPageIndex() - 1) * page.getPageSize();
            page.setPageIndex(page.getPageIndex() - 1);
        } else if (startIndex > taskList.size()) {
            Integer pageIndex = taskList.size() / page.getPageSize();
            startIndex = pageIndex * page.getPageSize();
            page.setPageIndex(pageIndex);
        }
        endIndex = (endIndex < taskList.size()) ? endIndex : taskList.size();
        return taskList.subList(startIndex, endIndex);
    }

   /**
    * @Method: formatTaskListPage
    * @Param: [taskList, page]
    * @Return: java.util.List<com.hex.ds.hdrs.period.task.po.PeriodTask>
    * @Description： 任务 分页处理
    * @Author： jd.chen
    * @Date： 2021/7/12 19:53
    * @Version： V1.0
    */
    public static List<PeriodTask> formatTaskListPage(List<PeriodTask> taskList, Page page) {
        if (ListUtil.isEmpty(taskList)) {
            page.setTotal(0);
            return taskList;
        }
        page.setTotal(taskList.size());
        Integer startIndex = page.getPageIndex() * page.getPageSize();
        Integer endIndex = (page.getPageIndex() + 1) * page.getPageSize();
        if (startIndex == taskList.size()) {
            startIndex = (page.getPageIndex() - 1) * page.getPageSize();
            page.setPageIndex(page.getPageIndex() - 1);
        } else if (startIndex > taskList.size()) {
            Integer pageIndex = taskList.size() / page.getPageSize();
            startIndex = pageIndex * page.getPageSize();
            page.setPageIndex(pageIndex);
        }
        endIndex = (endIndex < taskList.size()) ? endIndex : taskList.size();
        return taskList.subList(startIndex, endIndex);
    }

    /**
     * @Method: formatAgentListPage
     * @Param: [taskList, page]
     * @Return: java.util.List<com.hex.ds.hdrs.agent.vo.AgentSessionVO>
     * @Description： 节点 分页处理
     * @Author： jd.chen
     * @Date： 2021/7/12 20:21
     * @Version： V1.0
     */
    public static List<AgentSessionVO> formatAgentListPage(List<AgentSessionVO> taskList, Page page) {
        if (ListUtil.isEmpty(taskList)) {
            page.setTotal(0);
            return taskList;
        }
        page.setTotal(taskList.size());
        Integer startIndex = page.getPageIndex() * page.getPageSize();
        Integer endIndex = (page.getPageIndex() + 1) * page.getPageSize();
        if (startIndex == taskList.size()) {
            startIndex = (page.getPageIndex() - 1) * page.getPageSize();
            page.setPageIndex(page.getPageIndex() - 1);
        } else if (startIndex > taskList.size()) {
            Integer pageIndex = taskList.size() / page.getPageSize();
            startIndex = pageIndex * page.getPageSize();
            page.setPageIndex(pageIndex);
        }
        endIndex = (endIndex < taskList.size()) ? endIndex : taskList.size();
        return taskList.subList(startIndex, endIndex);
    }

    /**
     * @Method: formatAppListPage
     * @Param: [taskList, page]
     * @Return: java.util.List<com.hex.ds.hdrs.app.vo.AppSessionVO>
     * @Description： 应用 分页处理
     * @Author： jd.chen
     * @Date： 2021/7/12 20:21
     * @Version： V1.0
     */
    public static List<AppSessionVO> formatAppListPage(List<AppSessionVO> taskList, Page page) {
        if (ListUtil.isEmpty(taskList)) {
            page.setTotal(0);
            return taskList;
        }

        page.setTotal(taskList.size());
        Integer startIndex = page.getPageIndex() * page.getPageSize();
        Integer endIndex = (page.getPageIndex() + 1) * page.getPageSize();
        if (startIndex == taskList.size()) {
            startIndex = (page.getPageIndex() - 1) * page.getPageSize();
            page.setPageIndex(page.getPageIndex() - 1);
        } else if (startIndex > taskList.size()) {
            Integer pageIndex = taskList.size() / page.getPageSize();
            startIndex = pageIndex * page.getPageSize();
            page.setPageIndex(pageIndex);
        }
        endIndex = (endIndex < taskList.size()) ? endIndex : taskList.size();
        return taskList.subList(startIndex, endIndex);
    }

}
